<div id="Password-authentication-server"></div>
<div class="header">
<p>
Next: [[cvs: Using the client with password authentication#Using the client with password authentication|Password authentication client]], Up: [[cvs: Direct connection with password authentication#Direct connection with password authentication|Password authenticated]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>

----

<div id="Setting-up-the-server-for-password-authentication"></div>
===== Setting up the server for password authentication =====

First of all, you probably want to tighten the
permissions on the &lsquo;<tt>$CVSROOT</tt>&rsquo; and
&lsquo;<tt>$CVSROOT/CVSROOT</tt>&rsquo; directories.  See [[cvs: Security considerations with password authentication#Security considerations with password authentication|Password authentication security]], for more details.

<div id="index-pserver-_0028subcommand_0029"></div>
<div id="index-Remote-repositories_002c-port-specification-1"></div>
<div id="index-Repositories_002c-remote_002c-port-specification-1"></div>
<div id="index-Client_002fServer-Operation_002c-port-specification-1"></div>
<div id="index-pserver-_0028client_002fserver-connection-method_0029_002c-port-specification-1"></div>
<div id="index-kserver-_0028client_002fserver-connection-method_0029_002c-port-specification-1"></div>
<div id="index-gserver-_0028client_002fserver-connection-method_0029_002c-port-specification-1"></div>
<div id="index-port_002c-specifying-for-remote-repositories-1"></div>
<div id="index-Password-server_002c-setting-up"></div>
<div id="index-Authenticating-server_002c-setting-up"></div>
<div id="index-inetd_002c-configuring-for-pserver"></div>
<div id="index-xinetd_002c-configuring-for-pserver"></div>
On the server side, the file &lsquo;<tt>/etc/inetd.conf</tt>&rsquo;
needs to be edited so <code>inetd</code> knows to run the
command <code>cvs pserver</code> when it receives a
connection on the right port.  By default, the port
number is 2401; it would be different if your client
were compiled with <code>CVS_AUTH_PORT</code> defined to
something else, though.  This can also be specified in the CVSROOT variable
(see [[cvs: Remote repositories#Remote repositories|Remote repositories]]) or overridden with the CVS_CLIENT_PORT
environment variable (see [[cvs: All environment variables which affect CVS#All environment variables which affect CVS|Environment variables]]).

If your <code>inetd</code> allows raw port numbers in
&lsquo;<tt>/etc/inetd.conf</tt>&rsquo;, then the following (all on a
single line in &lsquo;<tt>inetd.conf</tt>&rsquo;) should be sufficient:

<div class="example" style="margin-left: 3.2em">
 2401  stream  tcp  nowait  root  /usr/local/bin/cvs
 cvs -f --allow-root=/usr/cvsroot pserver
</div>

(You could also use the
&lsquo;<code>-T</code>&rsquo; option to specify a temporary directory.)

The &lsquo;<code>--allow-root</code>&rsquo; option specifies the allowable
<small>CVSROOT</small> directory.  Clients which attempt to use a
different <small>CVSROOT</small> directory will not be allowed to
connect.  If there is more than one <small>CVSROOT</small>
directory which you want to allow, repeat the option.
(Unfortunately, many versions of <code>inetd</code> have very small
limits on the number of arguments and/or the total length
of the command.  The usual solution to this problem is
to have <code>inetd</code> run a shell script which then invokes
<small>CVS</small> with the necessary arguments.)

If your <code>inetd</code> wants a symbolic service
name instead of a raw port number, then put this in
&lsquo;<tt>/etc/services</tt>&rsquo;:

<div class="example" style="margin-left: 3.2em">
 cvspserver      2401/tcp
</div>

and put <code>cvspserver</code> instead of <code>2401</code> in &lsquo;<tt>inetd.conf</tt>&rsquo;.

If your system uses <code>xinetd</code> instead of <code>inetd</code>,
the procedure is slightly different.
Create a file called &lsquo;<tt>/etc/xinetd.d/cvspserver</tt>&rsquo; containing the following:

<div class="example" style="margin-left: 3.2em">
 service cvspserver
 <nowiki>{</nowiki>
    port        = 2401
    socket_type = stream
    protocol    = tcp
    wait        = no
    user        = root
    passenv     = PATH
    server      = /usr/local/bin/cvs
    server_args = -f --allow-root=/usr/cvsroot pserver
 <nowiki>}</nowiki>
</div>

(If <code>cvspserver</code> is defined in &lsquo;<tt>/etc/services</tt>&rsquo;, you can omit
the <code>port</code> line.)

Once the above is taken care of, restart your
<code>inetd</code>, or do whatever is necessary to force it
to reread its initialization files.

If you are having trouble setting this up, see
[[cvs: Trouble making a connection to a CVS server#Trouble making a connection to a CVS server|Connection]].

<div id="index-CVS-passwd-file"></div>
<div id="index-passwd-_0028admin-file_0029"></div>
Because the client stores and transmits passwords in
cleartext (almost&mdash;see [[cvs: Security considerations with password authentication#Security considerations with password authentication|Password authentication security]], for details), a separate <small>CVS</small> password
file is generally used, so people don&rsquo;t compromise
their regular passwords when they access the
repository.  This file is
&lsquo;<tt>$CVSROOT/CVSROOT/passwd</tt>&rsquo; (see [[cvs: The administrative files#The administrative files|Intro administrative files]]).  It uses a colon-separated
format, similar to &lsquo;<tt>/etc/passwd</tt>&rsquo; on Unix systems,
except that it has fewer fields: <small>CVS</small> username,
optional password, and an optional system username for
<small>CVS</small> to run as if authentication succeeds.  Here is
an example &lsquo;<tt>passwd</tt>&rsquo; file with five entries:

<div class="example" style="margin-left: 3.2em">
 anonymous:
 bach:ULtgRLXo7NRxs
 spwang:1sOp854gDF3DY
 melissa:tGX1fS8sun6rY:pubcvs
 qproj:XR4EZcEs0szik:pubcvs
</div>

(The passwords are encrypted according to the standard
Unix <code>crypt()</code> function, so it is possible to
paste in passwords directly from regular Unix
&lsquo;<tt>/etc/passwd</tt>&rsquo; files.)

The first line in the example will grant access to any
<small>CVS</small> client attempting to authenticate as user
<code>anonymous</code>, no matter what password they use,
including an empty password.  (This is typical for
sites granting anonymous read-only access; for
information on how to do the &quot;read-only&quot; part, see
[[cvs: Read-only repository access#Read-only repository access|Read-only access]].)

The second and third lines will grant access to
<code>bach</code> and <code>spwang</code> if they supply their
respective plaintext passwords.

<div id="index-User-aliases"></div>
The fourth line will grant access to <code>melissa</code>, if
she supplies the correct password, but her <small>CVS</small>
operations will actually run on the server side under
the system user <code>pubcvs</code>.  Thus, there need not be
any system user named <code>melissa</code>, but there
''must'' be one named <code>pubcvs</code>.

The fifth line shows that system user identities can be
shared: any client who successfully authenticates as
<code>qproj</code> will actually run as <code>pubcvs</code>, just
as <code>melissa</code> does.  That way you could create a
single, shared system user for each project in your
repository, and give each developer their own line in
the &lsquo;<tt>$CVSROOT/CVSROOT/passwd</tt>&rsquo; file.  The <small>CVS</small>
username on each line would be different, but the
system username would be the same.  The reason to have
different <small>CVS</small> usernames is that <small>CVS</small> will log their
actions under those names: when <code>melissa</code> commits
a change to a project, the checkin is recorded in the
project&rsquo;s history under the name <code>melissa</code>, not
<code>pubcvs</code>.  And the reason to have them share a
system username is so that you can arrange permissions
in the relevant area of the repository such that only
that account has write-permission there.

If the system-user field is present, all
password-authenticated <small>CVS</small> commands run as that
user; if no system user is specified, <small>CVS</small> simply
takes the <small>CVS</small> username as the system username and
runs commands as that user.  In either case, if there
is no such user on the system, then the <small>CVS</small>
operation will fail (regardless of whether the client
supplied a valid password).

The password and system-user fields can both be omitted
(and if the system-user field is omitted, then also
omit the colon that would have separated it from the
encrypted password).  For example, this would be a
valid &lsquo;<tt>$CVSROOT/CVSROOT/passwd</tt>&rsquo; file:

<div class="example" style="margin-left: 3.2em">
 anonymous::pubcvs
 fish:rKa5jzULzmhOo:kfogel
 sussman:1sOp854gDF3DY
</div>

When the password field is omitted or empty, then the
client&rsquo;s authentication attempt will succeed with any
password, including the empty string.  However, the
colon after the <small>CVS</small> username is always necessary,
even if the password is empty.

<small>CVS</small> can also fall back to use system authentication.
When authenticating a password, the server first checks
for the user in the &lsquo;<tt>$CVSROOT/CVSROOT/passwd</tt>&rsquo;
file.  If it finds the user, it will use that entry for
authentication as described above.  But if it does not
find the user, or if the <small>CVS</small> &lsquo;<tt>passwd</tt>&rsquo; file
does not exist, then the server can try to authenticate
the username and password using the operating system&rsquo;s
user-lookup routines (this &quot;fallback&quot; behavior can be
disabled by setting <code>SystemAuth=no</code> in the
<small>CVS</small> &lsquo;<tt>config</tt>&rsquo; file, see [[cvs: The CVSROOT%47config configuration file#The CVSROOT/config configuration file|config]]).

The default fallback behaviour is to look in 
&lsquo;<tt>/etc/passwd</tt>&rsquo; for this system password unless your
system has PAM (Pluggable Authentication Modules)
and your <small>CVS</small> server executable was configured to
use it at compile time (using <code>./configure --enable-pam</code> - see the
INSTALL file for more).  In this case, PAM will be consulted instead.
This means that <small>CVS</small> can be configured to use any password
authentication source PAM can be configured to use (possibilities
include a simple UNIX password, NIS, LDAP, and others) in its
global configuration file (usually &lsquo;<tt>/etc/pam.conf</tt>&rsquo;
or possibly &lsquo;<tt>/etc/pam.d/cvs</tt>&rsquo;).  See your PAM documentation
for more details on PAM configuration.

Note that PAM is an experimental feature in <small>CVS</small> and feedback is
encouraged.  Please send a mail to one of the <small>CVS</small> mailing lists
(<code>info-cvs@gnu.org</code> or <code>bug-cvs@gnu.org</code>) if you use the 
<small>CVS</small> PAM support.

'''WARNING: Using PAM gives the system administrator much more 
flexibility about how <small>CVS</small> users are authenticated but 
no more security than other methods.  See below for more.''' 

CVS needs an &quot;auth&quot; and &quot;account&quot; module in the 
PAM configuration file. A typical PAM configuration 
would therefore have the following lines 
in &lsquo;<tt>/etc/pam.conf</tt>&rsquo; to emulate the standard <small>CVS</small> 
system &lsquo;<tt>/etc/passwd</tt>&rsquo; authentication:

<div class="example" style="margin-left: 3.2em">
 cvs	auth	    required	pam_unix.so
 cvs	account	    required	pam_unix.so
</div>

The the equivalent &lsquo;<tt>/etc/pam.d/cvs</tt>&rsquo; would contain

<div class="example" style="margin-left: 3.2em">
 auth	    required	pam_unix.so
 account	    required	pam_unix.so
</div>

Some systems require a full path to the module so that
&lsquo;<tt>pam_unix.so</tt>&rsquo; (Linux) would become something like 
&lsquo;<tt>/usr/lib/security/$ISA/pam_unix.so.1</tt>&rsquo; (Sun Solaris).
See the &lsquo;<tt>contrib/pam</tt>&rsquo; subdirectory of the <small>CVS</small>
source distribution for further example configurations.

The PAM service name given above as &quot;cvs&quot; is just
the service name in the default configuration amd can be
set using
<code>./configure --with-hardcoded-pam-service-name=&lt;pam-service-name&gt;</code>
before compiling.  <small>CVS</small> can also be configured to use whatever
name it is invoked as as its PAM service name using
<code>./configure --without-hardcoded-pam-service-name</code>, but this
feature should not be used if you may not have control of the name
<small>CVS</small> will be invoked as.

Be aware, also, that falling back to system
authentication might be a security risk: <small>CVS</small>
operations would then be authenticated with that user&rsquo;s
regular login password, and the password flies across
the network in plaintext.  See [[cvs: Security considerations with password authentication#Security considerations with password authentication|Password authentication security]] for more on this.
This may be more of a problem with PAM authentication
because it is likely that the source of the system 
password is some central authentication service like
LDAP which is also used to authenticate other services.

On the other hand, PAM makes it very easy to change your password
regularly.  If they are given the option of a one-password system for
all of their activities, users are often more willing to change their
password on a regular basis.

In the non-PAM configuration where the password is stored in the
&lsquo;<tt>CVSROOT/passwd</tt>&rsquo; file, it is difficult to change passwords on a
regular basis since only administrative users (or in some cases
processes that act as an administrative user) are typicaly given
access to modify this file.  Either there needs to be some
hand-crafted web page or set-uid program to update the file, or the
update needs to be done by submitting a request to an administrator to
perform the duty by hand.  In the first case, having to remember to
update a separate password on a periodic basis can be difficult.  In
the second case, the manual nature of the change will typically mean
that the password will not be changed unless it is absolutely
necessary.

Note that PAM administrators should probably avoid configuring
one-time-passwords (OTP) for <small>CVS</small> authentication/authorization.  If
OTPs are desired, the administrator may wish to encourage the use of
one of the other Client/Server access methods.  See the section on
see [[cvs: Remote repositories#Remote repositories|Remote repositories]] for a list of other methods.

Right now, the only way to put a password in the
<small>CVS</small> &lsquo;<tt>passwd</tt>&rsquo; file is to paste it there from
somewhere else.  Someday, there may be a <code>cvs
passwd</code> command.

Unlike many of the files in &lsquo;<tt>$CVSROOT/CVSROOT</tt>&rsquo;, it
is normal to edit the &lsquo;<tt>passwd</tt>&rsquo; file in-place,
rather than via <small>CVS</small>.  This is because of the
possible security risks of having the &lsquo;<tt>passwd</tt>&rsquo;
file checked out to people&rsquo;s working copies.  If you do
want to include the &lsquo;<tt>passwd</tt>&rsquo; file in checkouts of
&lsquo;<tt>$CVSROOT/CVSROOT</tt>&rsquo;, see [[cvs: The checkoutlist file#The checkoutlist file|checkoutlist]].



----

<div class="header">
<p>
Next: [[cvs: Using the client with password authentication#Using the client with password authentication|Password authentication client]], Up: [[cvs: Direct connection with password authentication#Direct connection with password authentication|Password authenticated]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
This document was generated on <i>a sunny day</i> using [http://www.nongnu.org/texi2html/ <i>texi2html</i>].
